package controllers.Administrador;

import java.util.Collection;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import services.ActaService;
import services.ComunidadDeVecinosService;
import services.VecinoService;
import controllers.AbstractController;
import domain.ComunidadDeVecinos;
import domain.Vecino;
import forms.VecinoForm;

@Controller
@RequestMapping("/vecino/administrator")
public class VecinoAdministratorController extends AbstractController {

	@Autowired
	private VecinoService vecinoService;
	@Autowired
	private ComunidadDeVecinosService comunidadDeVecinosService;
	@Autowired
	private ActaService actaService;

	public VecinoAdministratorController() {
		super();
	}

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public ModelAndView list(@RequestParam int comunidadId) {
		ModelAndView result;
		ComunidadDeVecinos cv;
		Collection<Vecino> vecinos;

		cv = comunidadDeVecinosService.findOne(comunidadId);
		vecinos = vecinoService.findByCommunity(cv);

		result = new ModelAndView("vecinos/communityList");
		result.addObject("requestURI", "vecino/administrator/list.do");
		result.addObject("vecinos", vecinos);
		result.addObject("backURI",
				"/comunidad/administrator/edit.do?comunidadId=" + comunidadId);

		return result;
	}

	// Edition
	@RequestMapping(value = "/edit", method = RequestMethod.GET)
	public ModelAndView edit(@RequestParam int vecinoId) {
		ModelAndView result;
		VecinoForm vForm;
		Vecino vecino;
		Boolean isMoroso;
		Boolean tieneActaMoroso;

		vecino = vecinoService.findOne(vecinoId);
		vForm = vecinoService.vecinoToForm(vecino);
		isMoroso = vecino.getMoroso() == true;
		tieneActaMoroso = false;
		if (isMoroso) {
			tieneActaMoroso = !actaService.findActasMorosoByVecinoMoroso(
					vecinoId).isEmpty();

		}

		result = new ModelAndView("vecinos/edit");
		result.addObject("vForm", vForm);
		result.addObject("isMoroso", isMoroso);
		result.addObject("tieneActaMoroso", tieneActaMoroso);
		result.addObject("vecinoId", vecinoId);
		result.addObject("requestURI", "vecino/administrator/edit.do");
		result.addObject("backURI", "/welcome/index.do");

		return result;

	}

	@RequestMapping(value = "/edit", method = RequestMethod.POST, params = "save")
	public ModelAndView save(@Valid VecinoForm vForm, BindingResult binding) {
		ModelAndView result;
		Vecino v;
		Boolean eraseable;

		if (binding.hasErrors()) {
			result = createEditModelAndView(vForm);
		} else {
			try {

				v = vecinoService.reconstruct(vForm);
				vecinoService.save(v);
				result = new ModelAndView("redirect:../../");

			} catch (Throwable oops) {

				result = createEditModelAndView(vForm, "comunidad.commit.error");
			}
		}

		eraseable = false;
		result.addObject("requestURI", "vecino/administrator/edit.do");
		result.addObject("backURI", "/welcome/index.do");
		result.addObject("eraseable", eraseable);

		return result;
	}

	@RequestMapping(value = "/presidente", method = RequestMethod.GET)
	public ModelAndView presidente(@RequestParam int comunidadId) {
		ModelAndView result;
		ComunidadDeVecinos cv;
		Boolean hasPresident;
		Collection<Vecino> vecinos;
		Vecino presidente;

		cv = comunidadDeVecinosService.findOne(comunidadId);
		vecinos = vecinoService.findByCommunity(cv);
		hasPresident = cv.getPresidente() != null;

		result = new ModelAndView("vecinos/presidente");
		if (hasPresident) {
			presidente = cv.getPresidente();
			result.addObject("presidente", presidente);
		}
		result.addObject("requestURI", "vecino/administrator/list.do");
		result.addObject("hasPresident", hasPresident);
		result.addObject("vecinos", vecinos);
		result.addObject("comunidadId", comunidadId);
		result.addObject("backURI",
				"/comunidad/administrator/edit.do?comunidadId=" + comunidadId);

		return result;
	}

	@RequestMapping(value = "/hacerPresidente", method = RequestMethod.GET)
	public ModelAndView presidente(@RequestParam int comunidadId,
			int presidenteId) {
		ModelAndView result;

		try {

			vecinoService.hacerPresidente(comunidadId, presidenteId);
			result = new ModelAndView(
					"redirect:/comunidad/administrator/edit.do?comunidadId="
							+ comunidadId);

		} catch (Throwable oops) {
			result = new ModelAndView("vecinos/presidente");

			result = presidente(comunidadId);

			result.addObject("message", "presidente.commit.error");
			return result;

		}

		return result;
	}

	@RequestMapping(value = "/morosos", method = RequestMethod.GET)
	public ModelAndView morosos() {
		ModelAndView result;

		Collection<Vecino> morosos;
		Collection<Vecino> vecinosNoMorosos;
		VecinoForm vecinoForm;

		vecinoForm = new VecinoForm();
		morosos = vecinoService.findByMorosos();
		vecinosNoMorosos = vecinoService.finByNoMorosos();

		result = new ModelAndView("vecinos/morosos");

		result.addObject("requestURI", "vecino/administrator/morosos.do");
		result.addObject("morosos", morosos);
		result.addObject("vecinoForm", vecinoForm);
		result.addObject("vecinosNoMorosos", vecinosNoMorosos);

		result.addObject("backURI", "/welcome/index.do");

		return result;
	}

	@RequestMapping(value = "/quitarMorosidad", method = RequestMethod.GET)
	public ModelAndView quitarMoroso(@RequestParam int morosoId) {
		ModelAndView result;

		try {

			vecinoService.quitarMorosidad(morosoId);
			result = new ModelAndView(
					"redirect:/vecino/administrator/morosos.do");

		} catch (Throwable oops) {
			Collection<Vecino> morosos;
			Collection<Vecino> vecinosNoMorosos;
			VecinoForm vecinoForm2;

			vecinoForm2 = new VecinoForm();
			morosos = vecinoService.findByMorosos();
			vecinosNoMorosos = vecinoService.finByNoMorosos();

			result = new ModelAndView("vecinos/morosos");

			result.addObject("requestURI", "vecino/administrator/morosos.do");
			result.addObject("morosos", morosos);
			result.addObject("vecinoForm", vecinoForm2);
			result.addObject("vecinosNoMorosos", vecinosNoMorosos);

			result.addObject("backURI", "/welcome/index.do");

			result.addObject("message", "quitarMorosidad.commit.error");

			return result;

		}

		return result;
	}

	@RequestMapping(value = "/morosos", method = RequestMethod.POST, params = "hacerMoroso")
	public ModelAndView morosos(VecinoForm vecinoForm) {
		ModelAndView result;

		try {

			vecinoService.hacerMoroso(vecinoForm.getVecinoId());
			result = new ModelAndView(
					"redirect:/vecino/administrator/morosos.do");

		} catch (Throwable oops) {
			Collection<Vecino> morosos;
			Collection<Vecino> vecinosNoMorosos;
			VecinoForm vecinoForm2;

			vecinoForm2 = new VecinoForm();
			morosos = vecinoService.findByMorosos();
			vecinosNoMorosos = vecinoService.finByNoMorosos();

			result = new ModelAndView("vecinos/morosos");

			result.addObject("requestURI", "vecino/administrator/morosos.do");
			result.addObject("morosos", morosos);
			result.addObject("vecinoForm", vecinoForm2);
			result.addObject("vecinosNoMorosos", vecinosNoMorosos);

			result.addObject("backURI", "/welcome/index.do");

			result.addObject("message", "moroso.commit.error");
			return result;

		}

		return result;
	}

	// Ancillary methods
	protected ModelAndView createEditModelAndView(VecinoForm vForm) {
		ModelAndView result;

		result = createEditModelAndView(vForm, null);

		return result;
	}

	protected ModelAndView createEditModelAndView(VecinoForm vForm,
			String message) {
		ModelAndView result;

		result = new ModelAndView("vecinos/edit");

		result.addObject("vForm", vForm);
		result.addObject("message", message);

		return result;
	}
}
